#ifndef __LOCKBIG_H__
#define __LOCKBIG_H__
#include "osal.h"
#include "component.h"
/* 锁体动作类型 */
typedef enum
{
    LOCK_ACTION_INVALID,        //无效值
    LOCK_ACTION_LOCKED,         //上锁成功（上锁流程已结束，已回拖）
    LOCK_ACTION_LOCKED_NO_BACK, //上锁开关刚顶到,未回拖
    LOCK_ACTION_UNLOCK,         //开锁成功（开锁流程未结束，开关刚顶到）
    LOCK_ACTION_UNLOCK_BACK,    //开锁成功（开锁流程已结束，已回拖）
    LOCK_ACTION_UNLOCK_NO_BACK, //开锁成功（开锁流程已结束，未回拖）
    LOCK_ACTION_LOCKED_MACH,    //机械上锁成功
    LOCK_ACTION_UNLOCK_MACH,    //机械开锁成功
    LOCK_ACTION_NO_LOCKED,      //门未上锁
    LOCK_ACTION_DCI_ERROR,      //锁体过流
    LOCK_ACTION_ABNORMAL,       //锁体异常
    LOCK_ACTION_FORCE_UNLOCK,   //撬锁
    LOCK_ACTION_BUSY,           //锁体正忙
    LOCK_ACTION_DIR_LEFT,       //锁体上锁方向-左
    LOCK_ACTION_DIR_RIGHT,      //锁体上锁方向-右
    LOCK_ACTION_AUTO_DIR_CHECK_SUCCESS,//自学习成功
    LOCK_ACTION_AUTO_DIR_CHECK_FAILED,//自学习失败
    LOCK_ACTION_UNKNOW,         //锁状态未知（锁舌可能处于半开状态）
    LOCK_ACTION_UNLOCK_MACH_BACK,   //机械开锁回拖（机械开锁了，松开了旋钮，剪刀舌自动松开）
}LockAction_enum_t;

/*锁体控制方式*/
typedef enum
{
    LOCK_CTRL_VERIFY_OK,        //验证成功 应用层用得到
    LOCK_CTRL_LOCKED,			//上锁
    LOCK_CTRL_UNLOCK,			//开锁
    LOCK_CTRL_INVERSE,          //取反
	LOCK_CTRL_UNLOCK_BACK,		//开锁回拖
    LOCK_CTRL_STOP,		        //停止
    LOCK_CTRL_LOCKED_KEY,		//触摸关锁键上锁
}LockCtrl_enum_t;

/* 产测模式下的锁体测试模式 */
typedef enum
{
    LOCK_UNLOCK_TEST_MODE,      // 上锁/开锁测试模式
    MOTOR_TEST_MODE,            // 电机测试模式
	HALL_TEST_MODE,             // 计数霍尔测试模式(fvp)
    HALL_OC_TEST_MODE,          // 霍尔、光耦测试模式 -- 呆锁
    KEY_TEST_MODE,              //手动测试霍尔光耦
    SET_AUTO_CAL_FLAG_MODE,     //设置自学习标志
}Lock_Test_Mode_enum_t;

/*锁体上锁方向*/
typedef enum
{
    LOCKED_DIR_LEFT,      		//左侧上锁
    LOCKED_DIR_RIGHT,     		//右侧上锁
}LockedDir_enum_t;

/* 锁体上锁扭力 */
typedef enum
{
    LOCKED_TORQUE_SMALL = 1,    //小扭力
    LOCKED_TORQUE_HIGH,          //大扭力
}LockedTorque_enum_t;

/* 锁体子类型*/
typedef enum
{
    LOCK_SUB_TYPE_DEFAULT,          
    LOCK_SUB_TYPE_BIG,               //不带开关检测的霸王锁体
    LOCK_SUB_TYPE_BIG_PLUS,          //带开关检测的霸王锁体
}LockSubType_enum_t;

/* Lock组件消息类型 */
typedef struct
{
    UserAction_enum_t door;     //门动作
    LockAction_enum_t lock;     //锁体动作
    uint8_t sensorTestStatus[2];   //传感器测试结果
    LockSubType_enum_t type;   //锁类型
    UserAction_enum_t unlocks;  //开锁(剪刀舌)的状态
	uint8_t cmd; // 命令字
}LockMsg_t;

typedef struct 
{
    UserAction_enum_t action;   //动作
    char name[20];                 //传感器名称
}LockSensorAction_t;

/* 锁体模式 */
typedef enum
{
    LOCKED_MODE_NORMAL,                 //普通模式
    LOCKED_MODE_TEST,                   //锁体/电机测试模式
    LOCKED_MODE_HALL_OC_TEST,           //传感器测试模式
    LOCKED_MODE_KEY_TEST,               //按键测试传感器
}Locked_Mode_enum_t;

/* 传感器测试阶段结果 1个霍尔的锁没有左右霍尔/4个霍尔的锁不用区分左右挡板，左右霍尔*/
enum
{
	HALL_LEFT,                          //关锁霍尔左//关锁霍尔
    HALL_CENTER,                        //开锁霍尔
    HALL_RIGHT,                         //关锁霍尔右
    OC_LUCKED,                          //关锁到位光耦//开锁到位光耦1
    OC_UNLUCK,                          //开锁到位光耦//回拖到位光耦2
    BLADE_LEFT,                         //左挡板 
    BLADE_RIGHT,                        //右挡板
};


typedef enum{
	MOTO_STOP_LOCK_UNKNOWN = 0,
	MOTO_STOP_LOCK_OPEN,
	MOTO_STOP_LOCK_CLOSE,	
	MOTO_ROTATE,
}MOTO_STATUS_E;

/* 自动上锁邮箱命令 */
#define DISABLE_AUTO_LOCK (0x00)
#define ENABLE_AUTO_LOCK (0x01)
/* LockMsg cmd命令 */
#define AUTO_LOCK_START (0x01)//--
#define MSENSOR_REPORT_DIR (0x02) // 上报门磁状态//--

/* 锁体组件邮箱主题（APP->COMP） */
#define LOCK_MBOX_CTRL          	0
#define LOCK_MBOX_SET_DIR			1
#define LOCK_MBOX_SET_TORQUE		2
#define LOCK_MBOX_TESTCTRL       	3
#define LOCK_MBOX_IR_CTRL               4
#define LOCK_MBOX_SET_LOCK			    5
#define LOCK_MBOX_BATTERY               6
#define LOCK_MBOX_AUTO_LOCK             7
#define LOCK_MBOX_SET_LOCK_DAI_DIR      8
#define LOCK_MBOX_LOCK_MODE_SYNC        9
#define LOCK_MBOX_LOCK_SENSER_CHECK_WAKE   10

/* 正常模式操作上锁/开锁的接口 */
#define Lock_Ctrl(userType,event_code,key_id,ctrl)                     \
({                                                                 	   \
    uint8_t temp[5] = {LOCK_MBOX_CTRL,ctrl,userType,event_code,key_id};\
																	   \
    OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp)); 	               \
})                                                                 	   \

/* 设置锁定的接口 */
#define Lock_SetLock(flag)                                             \
({                                                                 	   \
    uint8_t temp[2] = {LOCK_MBOX_SET_LOCK,flag};                       \
																	   \
    OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp)); 	               \
})                                                                 	   \


/* 大电机锁体设置上锁方向的接口(1：左开门 2：右开门) */
#define LockBig_SetDir(dir)                                      	\
({                                                                 	\
    uint8_t temp[2] = {LOCK_MBOX_SET_DIR, dir};                   	\
																	\
    OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp)); 	            \
})                                                                 	\


/* 大电机锁体设置电机扭力的接口（1：小扭力、 2：大扭力） */
#define LockBig_SetTorque(torque)									\
({                                                                 	\
    uint8_t temp[2] = {LOCK_MBOX_SET_TORQUE, torque};				\
																	\
    OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp)); 	            \
})                                                                 	\


/* 产测测试接口 */
#define Lock_TestCtrl(testMode, data, dataLen)						    \
({                                                                   	\
    uint8_t temp[10] = {LOCK_MBOX_TESTCTRL, testMode, dataLen};		    \
    if(NULL != data && 0 != dataLen) {memcpy(&temp[3], data, dataLen);} \
    OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp)); 	                \
})                                                                 	    \

/* 无刷电机锁体校准电机接口 */
#define LockBigPro_SetRange(dir)                                  \
({                                                                 	\
    uint8_t temp[2] = {LOCK_MBOX_SET_RANGE, dir};                 \
																	\
    OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp)); 	            \
})      


#define LockBigPro_Reset()                                     \
({                                                             \
    uint8_t temp[2] = {LOCK_MBOX_SET_RESET, 0};           \
                                                                \
    OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp)); 	            \  
})

/* 产测光耦电源控制接口 */
#define Optocoupler_Ctrl(param)                        \
({                                                     \
    uint8_t temp[2] = {LOCK_MBOX_IR_CTRL,param};       \
                                                       \
    OSAL_MboxPost(COMP_LOCK, 0, &temp, sizeof(temp));  \
})

/**
 * @brief: 发送电压给lock组件
 * @param：vlot: 电压
 */
#define Lock_SetBatVolt(vlot)                            \
    ({                                                   \
        uint8_t temp[3] = {LOCK_MBOX_BATTERY, 0, 0};     \
        uint16_t vlot_temp = vlot;                       \
        memcpy(&temp[1], &vlot_temp, sizeof(vlot_temp)); \
        OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp)); \
    })

/**
 * @brief: 发送自动上锁给组件
 * @param：cmd: 0取消定时 1设置定时
 * @param：time: 定时时长
 */
#define Lock_SetAutolock(cmd, time)                                          \
    ({                                                                       \
        uint8_t temp[6] = {LOCK_MBOX_AUTO_LOCK, cmd, 0, 0, 0, 0};            \
        uint32_t auto_lock_time_temp = time;                                 \
        memcpy(&temp[2], &auto_lock_time_temp, sizeof(auto_lock_time_temp)); \
        OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp));                     \
    })

/**
 * @brief: 设置自动上锁方向给组件
 * @param：设置电机方向,0:逆时针上锁 1:顺时针上锁 0xFF未校准
 */
#define Lock_MotorDirSet(dir)                                \
    ({                                                       \
        uint8_t temp[2] = {LOCK_MBOX_SET_LOCK_DAI_DIR, dir}; \
        OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp));     \
    })

/**
 * @brief: 同步手自动模式
 * @param：0:自动模式 1:常开模式
 * @note: 3光耦0霍尔锁，自动模式休眠需要检测光耦状态判断是否需要上锁
 */
#define Lock_ModeSync(mode)                                \
    ({                                                       \
        uint8_t temp[2] = {LOCK_MBOX_LOCK_MODE_SYNC, mode}; \
        OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp));     \
    })

/**h
 * @brief: 设置后板检测唤醒使能
 * @param：0:失能 1:使能检测
 * @note: 前板开锁后，自动上锁时间过长，进入休眠，后板不需要检测唤醒
 */
#define Lock_SetSleepSenserCheck(flag)                       \
    ({                                                       \
        uint8_t temp[2] = {LOCK_MBOX_LOCK_SENSER_CHECK_WAKE, flag}; \
        OSAL_MboxPost(COMP_LOCK, 0, temp, sizeof(temp));     \
    })

/* 获取固件版本 */
#define Lock_GetVersion(ver)                               \
({                                                          \
    (OSAL_NvReadGlobal(COMP_LOCK,                          \
                       0,                   \
                       OSAL_OFFSET(LockNvData_stu_t, version), \
                       ver, sizeof(version)) != ERROR) ? SUCCESS : ERROR; \
})

#endif /* __LOCK_H__ */
